using System;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

using KLATencor.CommonApp.Infrastructure.StateMachine;

using Syncfusion.Windows.Forms.Diagram.Controls;
using Syncfusion.Windows.Forms.Diagram;

using StateMachine_Graphical_Editor.Forms;
using StateMachine_Graphical_Editor.Utils;
using StateMachine_Graphical_Editor.Utils.Forms_RunTime_Managment;

namespace StateMachine_Graphical_Editor.Shapes
{
    /// <summary>
    /// Provides graphical represetation for a single logical transition
    /// </summary>
    public class GTransition : LineConnector
    {

        #region Members:

        private long id = -1;

        private String abbrevName;
        private String sourceState;
        private String targetState;
        private String eventName;
        private String action;
        private String type;
        private String guard;

        private StateMachine machine;
        private Transition logicTransition;
        private bool crossHierarchy = false;
        private bool lastTransition = false;
        private bool multipleTransitions = false;

        private MultipleNames multipleNames = new MultipleNames(); //for multiple transition representation
        
        private readonly StatesForm form;

        #endregion

        #region C'tors:

        public GTransition(GTransition src)
            : base(src)
        {
            abbrevName = src.AbbrevName;
            sourceState = src.SourceState;
            targetState = src.TargetState;
            eventName = src.EventName;

            machine = src.Machine;
            
            logicTransition = src.LogicTransition;
        }

        public GTransition(System.Drawing.PointF pStart, System.Drawing.PointF pEnd, StatesForm owner)
            : base(pStart, pEnd)
        {
            this.form = owner;

            this.HeadDecorator.DecoratorShape = DecoratorShape.FilledFancyArrow;
            this.HeadDecorator.Size = new SizeF(12, 9);
            this.HeadDecorator.FillStyle.Color = Color.DarkGray;
            this.HeadDecorator.LineStyle.LineColor = Color.DarkGray;
            this.LineStyle.LineColor = Color.DarkGray;
            this.LineStyle.LineWidth = 1;

        }

        public GTransition(System.Drawing.PointF pStart, System.Drawing.PointF pEnd, Transition transition, StatesForm owner)
            : this(pStart, pEnd, owner)
        {
            abbrevName = transition.AbbrevName;
            sourceState = transition.Source.Name;
            targetState = transition.Target.Name;
            eventName = transition.EventName;
            id = transition.TransitionNumber;

            logicTransition = transition;
            machine = transition.StateMachine;
        }

        public GTransition(LineConnector baseShape)
            : base(baseShape) {}

        #endregion

        #region Geters/Seters:

        public long Id
        {
            get { return id; }
            set { id = value; }
        }

        public String AbbrevName
        {
            get { return abbrevName; }
            set { abbrevName = value; }
        }

        public String TargetState
        {
            get { return targetState; }
            set { targetState = value; }
        }

        public String SourceState
        {
            get { return sourceState; }
            set { sourceState = value; }
        }

        public String EventName
        {
            get { return eventName; }
            set { eventName = value; }
        }

        public String Action
        {
            get { return action; }
            set { action = value; }
        }
        public String Type
        {
            get { return type; }
            set { type = value; }
        }
        public String Guard
        {
            get { return guard; }
            set { guard = value; }
        }

        public String TransitionName
        {
            get { return Name; }
            set
            {
                Name = value;
                multipleNames.addName(Name); //add original name in creation
            }
        }

        public StateMachine Machine
        {
            get { return machine; }
        }

        public Transition LogicTransition
        {
            get { return logicTransition; }
        }

        public bool LastTransition
        {
            get { return lastTransition; }
            set 
            { 
                lastTransition = value; 
                System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
                
                if (lastTransition == true)
                {
                    this.form.LastTransition = this;
                    this.HeadDecorator.FillStyle.Color = Color.Red;
                    this.HeadDecorator.LineStyle.LineColor = Color.Red;
                    this.LineStyle.LineColor = Color.Red;
                    this.LineStyle.LineWidth = 3;
                }
                else
                {
                    //restore graphical characteristics of the transition:
                    this.LineStyle.LineWidth = 1;
                    CrossHierarchy = crossHierarchy;
                }

                System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = true;
            }
        }

        public Form Form
        {
            get { return this.form; }
        }

        public bool CrossHierarchy
        {
            get { return crossHierarchy; }
            set 
            { 
                crossHierarchy = value;
                if (crossHierarchy)
                {
                    LineStyle.DashStyle = System.Drawing.Drawing2D.DashStyle.DashDot;
                    HeadDecorator.FillStyle.Color = Color.Black;
                    HeadDecorator.LineStyle.LineColor = Color.Black;
                    LineStyle.LineColor = Color.Black;
                }
                else
                {
                    LineStyle.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
                    HeadDecorator.FillStyle.Color = Color.DarkGray;
                    HeadDecorator.LineStyle.LineColor = Color.DarkGray;
                    LineStyle.LineColor = Color.DarkGray;
                }

            }
        }

        public bool MultipleTransitions
        {
            get { return multipleTransitions; }
            set { multipleTransitions = value; }
        }

        public string DisplayNames
        {
            get { return multipleNames.getDisplayNames(); }
        }

        public MultipleNames DisplayNamesList
        {
            get { return multipleNames; }
        }

        #endregion

        #region OnTransitionOccured event handler:

        public void handleEventForGTransition(StateChangeEventArgs args)
        {
            //this check is to make sure tht only the current form's nodes response to the event:
            if (this.logicTransition == null)
                return;
            if (!FormsManager.getManager().isTopForm(form))
                return;

            if (args.Transition != null &&
                machine.LastTransition != null &&
                machine.LastTransition.Equals(this.logicTransition))
            {
                this.LastTransition = true;
            }
            else
                this.LastTransition = false;
        }

        protected override void OnMouseEnter()
        {
            if (FromNode is GInitial || ToNode is GFinal)
                return;
            form.toolTip.SetToolTip(form.Diagram, this.DisplayNames);
        }

        #endregion

        #region Methods:

        public void addName(string transitionName)
        {
            multipleNames.addName(transitionName);
        }

        #endregion
    }
}
